﻿using GFluentCode.CodeMaker.Template;
using GFluentCode.Entity;
using GFluentCode.ORM.SqlServer;
using GFluentCode.Tools;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace GFluentCode.CodeMaker
{
    public partial class FrmCustomClass : Form
    {
        SqlServerORM _sqlOrm;

        List<GFluentColumnEntity> _cols = new List<GFluentColumnEntity>();

        string _savePath;

        string _tableSql;
        string _fields;

        public FrmCustomClass(SqlServerORM sqlOrm, string savePath)
        {
            InitializeComponent();

            _sqlOrm = sqlOrm;
            _savePath = savePath;

            Load += (s, e) =>
            {
                LbTables.Items.Clear();

                var tns = _sqlOrm.QueryTableNames().Select(t => t.TableName).ToList();

                foreach (var item in tns)
                {
                    LbTables.Items.Add(item);
                }

                TabEntity.TabPages.Clear();
                TabORM.TabPages.Clear();
            };
        }

        private void LbTables_DoubleClick(object sender, EventArgs e)
        {
            if (LbTables.SelectedItem == null) return;

            var table = _sqlOrm.QueryTableEntity(LbTables.SelectedItem.ToString());

            MakeTableBox(table);
        }

        void MakeTableBox(GFluentTableEntity table)
        {
            var uc = FlowTable.Controls.Cast<UcTable>().FirstOrDefault(t => t.TableName.Equals(table.TableName));

            if (uc != null) return;

            uc = new UcTable(table)
            {
                DoubleClicked = DoubleClose,
                PropertyChecked = PropertyChanged
            };

            FlowTable.Controls.Add(uc);
        }

        void DoubleClose(UcTable uc, string tableName)
        {
            var cols = _cols.Where(t => t.TableName.Equals(tableName));
            foreach (var col in cols)
            {
                _cols.Remove(col);
            }

            FlowTable.Controls.Remove(uc);

            MakeSql();
        }

        void PropertyChanged(GFluentColumnEntity col, bool isChecked)
        {
            if (isChecked)
            {
                //加
                _cols.Add(col);
            }
            else
            {
                //减
                _cols.Remove(col);
            }

            MakeSql();
        }

        void MakeSql()
        {
            var sql = @"
Select {0}
From {1}
Where 1=1 ";
            if (_cols.Count <= 0)
            {
                TxtSql.Text = string.Empty;
                return;
            }
            var cols = string.Join(",", _cols.Select(t => t.ColumnName)).TrimEnd(',');

            _fields = cols;

            var tables = _cols.Select(t => t.TableName).Distinct().ToList();

            var tableSql = string.Empty;
            if (tables.Count() > 1)
            {
                tableSql = tables[0];

                for (var i = 1; i < tables.Count; i++)
                {
                    tableSql += $@"
Left Join {tables[i]} on
";
                }
            }
            else tableSql = tables[0];

            _tableSql = tableSql;

            TxtSql.Text = sql.GToFormat(cols, tableSql).TrimStart('\r','\n') + "{0}";
        }

        private void BtnCreate_Click(object sender, EventArgs e)
        {
            var entityName = TxtEntityName.Text;
            var entityNs = TxtEntityNS.Text;
            var ormNs = TxtOrmNs.Text;


            if (entityName.GIsEmpty(true) || entityNs.GIsEmpty() || ormNs.GIsEmpty())
            {
                MessageBox.Show("请填写实体名和命名空间");
                return;
            }

            CreateTabControl(TabEntity, entityName);
            CreateTabControl(TabORM, entityName);

            TabEntity.Write(entityName, _cols.ToEntityTemplate(entityName, entityNs));
            TabORM.Write(entityName, CustomORMTemplate.ToCustomORMTemplate(entityNs, ormNs, TxtSql.Text, entityName, _tableSql, _fields));
        }

        void SaveFile(string path, string type, string tableName, string ext, TabControl tab)
        {
            var myPath = Path.Combine(path, type);
            if (!Directory.Exists(myPath))
                Directory.CreateDirectory(myPath);
            var tp = tab.TabPages.Cast<TabPage>().First(x => x.Text.Equals(tableName));
            myPath = Path.Combine(myPath, tableName + ext + ".cs");
            File.AppendAllText(myPath, tp.Controls[0].Text);
        }

        void CreateTabControl(TabControl tab, string entityName)
        {
            tab.TabPages.Clear();

            var tp = new TabPage(entityName);
            var txt = new TextBox();
            txt.Name = $"Txt{entityName}{tab.Name.ToString().Replace("Tab", "")}";
            txt.Multiline = true;
            txt.Dock = DockStyle.Fill;
            tp.Controls.Add(txt);
            tab.TabPages.Add(tp);

        }

        private void BtnSave_Click(object sender, EventArgs e)
        {
            SaveFile(_savePath, "CustomEntity", TabEntity.TabPages[0].Text, "Entity", TabEntity);
            SaveFile(_savePath, "CustomORM", TabORM.TabPages[0].Text, "ORM", TabORM);
        }
    }
}
